/*
 * The class that converter from test suite to tree.
 * 
 * @(#)ConvertTestSuiteToTree.java
 *
 * Revision:
 * Author                                         Date           
 * --------------------------------------------   ------------   
 * Ana Emilia Victor Barbosa Coutinho             01/12/2011    
 */
package br.edu.ufcg.splab.techniques.converter;

import java.util.List;
import java.util.UUID;

import br.edu.ufcg.splab.core.InterfaceEdge;
import br.edu.ufcg.splab.core.InterfaceVertex;
import br.edu.ufcg.splab.core.graph.Tree;
import br.edu.ufcg.splab.generator.TestCase;
import br.edu.ufcg.splab.generator.TestSuite;



public class ConvertTestSuiteToTree {

	/*
     * The tree resulting of the convert.
     */
	private Tree tree;
	
	/**
	 * Constructor the converter from test suite to tree. 
	 * @param graph The graph to be converted. 
	 */
	public ConvertTestSuiteToTree(TestSuite testSuite){	
		converter(testSuite);			
	}
	
	/**
	 * Returns the resultant tree of the convert.
	 * @return The resultant tree of the convert from test suite.
	 */
	public Tree getTree(){	
		return tree;
	}
	
	/*
	 * Convert the test suite in a tree, conforming to the algorithm described in the paper.
	 * @param The test suite to be converted. 
	 */
	private void converter(TestSuite testSuite){
		this.tree = new Tree();		
		List<TestCase> ts = testSuite.getTestSuite();	
		
		InterfaceVertex currentNodeTree = null;
		for(TestCase tc:ts){
			currentNodeTree = getTree().getRoot();
			
			for(InterfaceEdge edge:tc.getTestCase()){				
				if(currentNodeTree == null){
					getTree().addNode(edge.getFrom().getLabel());
					currentNodeTree = getTree().getRoot();
				}
				currentNodeTree = traverse(edge,currentNodeTree);				
			}
		}
	}
	
	/*
	 * Recursive method to traverse an test case and convert it in tree elements.
	 * @param currentVertex The current vertex to be traversed an graph. In the beginning is the root.
	 * @param currentNode The current node in the recursion.
	 * @throws IOException 
	 */
	private InterfaceVertex traverse(InterfaceEdge currentEdgeTC, InterfaceVertex currentNodeTree){		
		if(isOutEdgesToNodeTree(currentNodeTree, currentEdgeTC)){
			currentNodeTree = nextEdgeTree(currentNodeTree, currentEdgeTC);
		}else{
			UUID newNode = getTree().addNode(currentEdgeTC.getTo().getLabel());					
			InterfaceEdge newEdge = getTree().addEdge(currentNodeTree.getUUID(), currentEdgeTC.getLabel(), newNode);
			newEdge.setType(currentEdgeTC.getType());
			currentNodeTree = newEdge.getTo();
		}
		return currentNodeTree;
	}
	
	private boolean isOutEdgesToNodeTree(InterfaceVertex currentNodeTree, InterfaceEdge currentEdgeTC){
		for(InterfaceEdge ed: currentNodeTree.getOutTransitions()){
			if(ed.toString().equals(currentEdgeTC.toString())){				
				return true;
			}
		}
		return false;
	}
	
	private InterfaceVertex nextEdgeTree(InterfaceVertex currentNodeTree, InterfaceEdge currentEdgeTC){
		for(InterfaceEdge ed: currentNodeTree.getOutTransitions()){
			if(ed.toString().equals(currentEdgeTC.toString())){
				return ed.getTo();
			}
		}
		return null;
	}
	
}
